package com.ruoyi.web.controller.app;

import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.alibaba.druid.support.json.JSONUtils;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.domain.DdOrder;
import com.ruoyi.system.domain.POLIPay;
import com.ruoyi.system.domain.POLIResponse;
import com.ruoyi.system.service.IDdOrderService;
import com.ruoyi.web.core.config.Configs;
import com.ruoyi.web.core.config.WebSocket;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Base64;
import java.util.Map;

/**
 * @ProjectName: ruoyi
 * @ClassName: PayController
 * @Description:
 * @Author: @Abeiv
 * @Date: 2020-3-8 15:56
 */
@Api("支付接口")
@RestController
@RequestMapping("/pay")
public class PayController extends BaseController {

    @Autowired
    IDdOrderService ddOrderService;


    @RequestMapping("/poli/success")
    public void s() {
        System.err.println("success____________________________");
    }

    @RequestMapping("/poli/Failure")
    public void Failure() {
        System.err.println("Failure_________________________交易失败");
    }

    @RequestMapping("/poli/Cancellation")
    public void Cancellation() {
        System.err.println("Cancellation____________________________取消支付");
    }

    @RequestMapping("/poli/Notification")
    public void Notification(String Token) {
        System.err.println("ToKen：" + Token);
        POLIResponse result = SendPoliGetTransactionRequest(Token);
        switch (result.getTransactionStatus()) {
            case "Initiated":
                //开始

                break;
            case "FinancialInstitution Selected":
                //已选择财务机构

                break;
            case "EulaAccepted":
                //接受POLI协议

                break;
            case "InProcess":
                //进行中

                break;
            case "Unknown":
                //未知

                break;
            case "Completed":
                //完成支付
                logger.debug(result.toString());
                DdOrder d = ddOrderService.selectDdOrderById(result.getMerchantReference());
                if(d.getStatus().equals("2")){
                    DdOrder ddOrder = new DdOrder();
                    ddOrder.setUuid(result.getMerchantReference());

                    ddOrder.setStatus("3");
                    ddOrder.setTransactionRefNo(result.getTransactionRefNo());
                    ddOrder.setPay("0");
                    ddOrderService.updateDdOrder(ddOrder);
                    ddOrder = ddOrderService.selectDdOrderById(ddOrder.getUuid());
                    AjaxResult aj = new AjaxResult(AjaxResult.Type.SUCCESS,"支付成功",ddOrder.getUuid());
                    WebSocket.AppointSending("0-"+ddOrder.getFromId(), JSONUtil.toJsonStr(aj));
                    WebSocket.GroupSending(JSONUtil.toJsonStr(new AjaxResult(AjaxResult.Type.SUCCESS,"新订单")),1);
                }
                break;
            case "Cancelled":
                //取消支付

                break;
            case "Failed":
                //失败

                break;
            case "ReceiptUnverified":
                //未核实收据

                break;
            case "TimedOut":

                //超时订单
                break;
            default:
                System.err.println("未找到状态信息：" + result.getTransactionStatus());
        }
    }


    @ApiOperation("发起POLI支付")
    @PostMapping("/sendPOLI")
    public String SendPoliInitiateRequest(DdOrder ddOrder) {
        try {
            String query = Configs.POLI_URL + "Initiate";
//Use Your Own JSON builder (example like GSON), Or make sure this string is in one line
            String json = "{ 'Amount':'" + ddOrder.getMoney() + "'," +
                    "'CurrencyCode':'AUD'," + "'MerchantReference':'" + ddOrder.getUuid() + "', " +
                    "'MerchantHomepageURL':'http://ambcc.nat300.top', " +
                    "'SuccessURL':'http://ambcc.nat300.top/pay/poli/success'," +
                    "'FailureURL':'http://ambcc.nat300.top/pay/poli/Failure'," +
                    "'CancellationURL':'http://ambcc.nat300.top/pay/poli/Failure'," +
                    "'NotificationURL':'http://ambcc.nat300.top/pay/poli/Notification'" +
                    "}";

            logger.debug(json);

            URL url = new URL(query);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5000);

            String accesscode = Configs.MERCHANT_CODE + ":" + Configs.AUTHENTICATION_CODE; //ADD YOUR CREDENTIALS
            String encodedAuthString = Base64.getEncoder().encodeToString(accesscode.getBytes());

            conn.setRequestProperty("authorization", "Basic " + encodedAuthString);
            conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");

            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setRequestMethod("POST");

            OutputStream os = conn.getOutputStream();
            os.write(json.getBytes("UTF-8"));
            os.close();

            // read the response
            InputStream in = new BufferedInputStream(conn.getInputStream());

            byte[] contents = new byte[1024];
            int bytesRead = 0;

            String poliResponse = "";

            while ((bytesRead = in.read(contents)) != -1) {
                poliResponse += new String(contents, 0, bytesRead);
            }

            System.out.print(poliResponse);//Process the JSON Response and Redirect to NavigateURL

            in.close();
            conn.disconnect();
            Map m = (Map) JSONUtils.parse(poliResponse);
            POLIPay poliPay = new POLIPay();
            poliPay.setSuccess((Boolean) m.get("Success"));
            poliPay.setNavigateURL((String) m.get("NavigateURL"));
            poliPay.setErrorCode((Integer) m.get("ErrorCode"));
            poliPay.setErrorMessage((String) m.get("ErrorMessage"));
            poliPay.setTransactionRefNo((String) m.get("TransactionRefNo"));
            System.err.println("------------------------》" + poliPay.toString());
            ddOrder.setPay("0");
            ddOrder.setTransactionRefNo(poliPay.getTransactionRefNo());
            ddOrder.setUpdateBy(ddOrder.getFromName());
            ddOrder.setUpdateTime(DateUtils.getNowDate());
            ddOrderService.updateDdOrder(ddOrder);
            return poliResponse;
        } catch (IOException ex) {
            System.out.print(ex);
        }
        return "";
    }

    public static POLIResponse SendPoliGetTransactionRequest(String token) {
        try {

            String query = Configs.POLI_URL + "GetTransaction?token=" + token;

            URL url = new URL(query);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5000);

            String accesscode = Configs.MERCHANT_CODE + ":" + Configs.AUTHENTICATION_CODE; //ADD YOUR OWN CREDENTIALS
            String encodedAuthString = Base64.getEncoder().encodeToString(accesscode.getBytes());

            conn.setRequestProperty("authorization", "Basic " + encodedAuthString);

            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setRequestMethod("GET");

            // read the response
            InputStream in = new BufferedInputStream(conn.getInputStream());

            byte[] contents = new byte[1024];
            int bytesRead = 0;

            String poliResponse = "";

            while ((bytesRead = in.read(contents)) != -1) {
                poliResponse += new String(contents, 0, bytesRead);
            }
            in.close();
            conn.disconnect();
            POLIResponse result = JSONUtil.toBean(poliResponse, POLIResponse.class);
            System.out.print(result.toString());
            return result;

        } catch (IOException ex) {
            System.out.print(ex);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
